package hyperNexusModel

import (
	"fmt"
	"reflect"
	"strings"
)

type HyperNexusModel struct {
	Name            string
	EntityModelData interface{}
	TablePrefix     string
	ShardConfig     *ShardConfig
}

func (m *HyperNexusModel) SetTabelPrefix(prefix string) {
	m.TablePrefix = prefix
}

func (m *HyperNexusModel) TableName() string {
	return fmt.Sprintf("%s%s", m.TablePrefix, strings.ToLower(m.Name))
}

func (m *HyperNexusModel) ShareTabelName(shardNum int) string {
	return fmt.Sprintf("%s%s_%d", m.TablePrefix, strings.ToLower(m.Name), shardNum)
}

// 获取分表配置名称
func (m *HyperNexusModel) GetShardDataTabelName(shareValue string) (string, error) {
	if m.ShardConfig != nil && m.ShardConfig.GetShardSuffixFunc != nil {
		shareTabelNum := m.ShardConfig.GetShardSuffixFunc(shareValue, m.ShardConfig.ShardNum)
		return m.ShareTabelName(shareTabelNum), nil
	}
	return m.TableName(), nil
}

func (m *HyperNexusModel) GetShardTableNum(shareValue string) int {
	if m.ShardConfig != nil && m.ShardConfig.GetShardSuffixFunc != nil {
		shareTabelNum := m.ShardConfig.GetShardSuffixFunc(shareValue, m.ShardConfig.ShardNum)
		return shareTabelNum
	}
	return -1
}

func NewEntity(m *HyperNexusModel) interface{} {
	// 获取类型
	t := reflect.TypeOf(m.EntityModelData)
	// 创建实例的指针Value
	ptrValue := reflect.New(t.Elem())
	// i := ptrValue.Interface()
	return ptrValue.Interface()
}

func NewHyperNexusModel(name string,
	entityModelData interface{},
	sConfig *ShardConfig) *HyperNexusModel {
	return &HyperNexusModel{
		Name:            name,
		EntityModelData: entityModelData,
		ShardConfig:     sConfig,
	}
}
